package lingou.homework.postbar.service.mock;

import lingou.homework.postbar.dao.*;
import lingou.homework.postbar.domain.*;
import lingou.homework.postbar.service.PostService;
import lingou.homework.postbar.service.UserService;
import lingou.homework.postbar.service.enums.PostTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Random;

@Service
public class MockService {

    @Autowired
    PostService postService;
    @Autowired
    UserService userService;
    public void mockUser(int c) {
        // user
        for (int i = 0; i < c; i++) {
            userService.register(randomStr(5, 10), randomStr(8, 14), randomStr(6, 10));
        }
    }
    public void mockPubPost(int c) {
        List<User> allUsers = userService.getAllUsers();
        for(int i = 0; i<c; i++) {
            User sample = sample(allUsers);
            postService.publishPost(sample.getUserId(), shortStr(), longStr(), Math.random() < 0.2, Math.random() < 0.2);
        }
    }
    public void mockComment(int c) {
        List<User> allUsers = userService.getAllUsers();
        List<Post> posts = postService.getPublicPosts(0, null, null, null, null, false)
                .stream().filter(post -> post.getDraw() == 0).toList();
        // comment
        for(int i = 0; i<c; i++) {
            User user = sample(allUsers);
            Post post = sample(posts);
            postService.reply(post.getPostId(), user.getUserId(), longStr(), Math.random() < 0.2, null);
        }
    }
    public void mockComment2(int c) {
        List<User> allUsers = userService.getAllUsers();
        List<Post> posts = postService.getPublicPosts(0, null, null, null, null, false);
        // 2comment
        for(int i = 0; i<c; i++) {
            User user = sample(allUsers);
            Post post = sample(posts);
            List<Post> allReply = postService.getAllReply(post.getPostId());
            if(allReply.size() == 0) continue;
            Post reply = sample(allReply);
            postService.reply(reply.getPostId(), user.getUserId(), longStr(), Math.random() < 0.2, null);
            if(Math.random() < 0.5) {
                Post reply2 = sample(postService.getAllReply(reply.getPostId()));
                postService.reply(reply.getPostId(), user.getUserId(), longStr(), Math.random() < 0.2, reply2.getUserId());
            }
        }
    }

    public void mockBox(int c, double[] d){
        List<User> allUsers = userService.getAllUsers();
        for(int i = 0; i<c; i++) {
            User asker = sample(allUsers);
            User owner = sample(allUsers);
            if(asker.getUserId().equals(owner.getUserId())) continue;
            long pl = postService.postQuestion(asker.getUserId(), owner.getUserId(), shortStr(), longStr());
            System.out.println(asker.getUserId()+"向"+owner.getUserId()+"提问: "+ pl);
            while (true){
                if(Math.random() < d[0]) break;
                long l = postService.replyBoxPost(owner.getUserId(), pl, longStr(), Math.random() < 0.7);
                System.out.println(owner.getUserId()+"回复"+asker.getUserId()+": "+l);
                if(Math.random() < d[0]) break;
                l = postService.replyBoxPost(asker.getUserId(), pl, longStr(), false);
                System.out.println(asker.getUserId()+"回复"+owner.getUserId()+": "+l);
            }
        }
    }

    @Autowired
    PubPostMapper pubPostMapper;
    @Autowired
    NoticePostMapper noticePostMapper;
    @Autowired
    NewsPostMapper newsPostMapper;
    @Autowired
    BoxMapper boxMapper;
    @Autowired
    CommentMapper commentMapper;

    public void fixType(){
        pubPostMapper.selectList(null).forEach(x ->
        {
            Post post = postMapper.selectById(x.getPostId());
            post.setType((long) PostTypeEnum.PUB.ordinal());
            postMapper.updateById(post);
        });
        newsPostMapper.selectList(null).forEach(x ->
        {
            Post post = postMapper.selectById(x.getPostId());
            post.setType((long) PostTypeEnum.NEWS.ordinal());
            postMapper.updateById(post);
        });
        noticePostMapper.selectList(null).forEach(x ->
        {
            Post post = postMapper.selectById(x.getPostId());
            post.setType((long) PostTypeEnum.NOTICE.ordinal());
            postMapper.updateById(post);
        });
        boxMapper.selectList(null).forEach(x ->
        {
            Post post = postMapper.selectById(x.getPostId());
            post.setType((long) PostTypeEnum.BOX.ordinal());
            postMapper.updateById(post);
        });
        commentMapper.selectList(null).forEach(x ->
        {
            Post post = postMapper.selectById(x.getChildId());
            post.setType((long) PostTypeEnum.COMMENT.ordinal());
            postMapper.updateById(post);
        });
    }

    @Autowired
    PostSnapshotMapper postSnapshotMapper;
    @Autowired
    PostMapper postMapper;
    @Transactional
    public void fixComment(){
        List<Comment> comments = commentMapper.selectList(null);
        comments.forEach(comment -> {
            Post post = postService.getPost(comment.getChildId());
            if(post.getSnapshotId() == null) return;
            System.out.println(post.getPostId());
            PostSnapshot postSnapshot = postSnapshotMapper.selectById(post.getSnapshotId());
            post.setPreview(postSnapshot.getContent());
            postMapper.updateById(post);
            postMapper.setSnapshotNull(post.getPostId());
            postSnapshotMapper.deleteById(postSnapshot);
        });
    }

    private static <T> List<T> sample(List<T> list, double rate){
        return list.stream().filter(x -> Math.random() < rate).toList();
    }

    private static <T> T sample(List<T> list){
        return list.get(new Random().nextInt(list.size()));
    }

    private static String randomStr(int a, int b){
        Random random = new Random();
        int n = random.nextInt(a, b+1);
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i<n; i++) {
            builder.append((char)(random.nextInt(32, 127)));
        }
        return builder.toString();
    }

    private static String randomStr(int n) {
        return randomStr(n, n);
    }

    private static String shortStr(){
        return randomStr(6,18);
    }

    private static String longStr(){
        StringBuilder stringBuilder = new StringBuilder();
        Random random = new Random();
        int l = random.nextInt(3, 20);
        for(int i = 0; i< l; i++){
            stringBuilder.append("<p>").append(randomStr(10, 100)).append("</p>");
        }
        return stringBuilder.toString();
    }

}
